package database

import (
	"fmt"
	"regexp"
	"strings"
	"time"

	"github.com/blog/config"
	"go.uber.org/zap"
	"gorm.io/driver/mysql"
	"gorm.io/gorm"
	"github.com/blog/model"
)

var DB *gorm.DB
var err error

func InitMysql(config *config.AppConfig) (*gorm.DB, error) {
	databaseConfig := config.Database
	url := databaseConfig.Mysql.Url
	if len(url) == 0 {
		return nil, fmt.Errorf("database url is empty")
	}
	db, err := gorm.Open(mysql.Open(url), &gorm.Config{})
	if err != nil {
		errStr := fmt.Sprintf("%s", err.Error())
		if strings.Contains(errStr, "Unknown database") {
			db = autoCreateDatabase(databaseConfig.Mysql.Url)
		}
		if db == nil {
			return nil, err
		}
	}
	sqlDB, _ := db.DB()
	sqlDB.SetMaxIdleConns(databaseConfig.Mysql.MaxIdleConn)
	sqlDB.SetMaxOpenConns(databaseConfig.Mysql.MaxOpenConn)
	sqlDB.SetConnMaxLifetime(time.Hour)
	sqlDB.SetConnMaxIdleTime(time.Minute * time.Duration(databaseConfig.Mysql.MaxIdleTime))
	err = sqlDB.Ping()
	if err != nil {
		zap.S().Error("database connection failed", zap.Error(err))
		return nil, err
	}
	//自动建表
	autoCreateTable(db)
	return db, nil
}

func autoCreateDatabase(url string) *gorm.DB {
	zap.S().Infof("数据库不存在，准创建...")

// 正则表达式  `/([^/?]+)\?` 
//  `/`  匹配 URL 路径前的斜杠
//  ([^/?]+)  捕获非斜杠非问号的连续字符 → 就是库名
//  `\?`  匹配问号，确保后面是参数开始


/*


字符 								含义 
 /  								匹配字面量斜杠  /  
 (  								开始一个捕获组（后面要提取的内容） 
 [  								开始一个字符类（匹配方括号内的任意一个字符） 
 ^  								在字符类里表示取反：“不是这些字符” 
 /  								字面斜杠（被取反，即不能是斜杠） 
 ?  								字面问号（被取反，即不能是问号） 
 ]  									结束字符类 
 +  								量词：前面的字符类重复 1 次或多次（贪婪） 
 )  								结束捕获组 
 \?  							匹配字面量问号  ? （因为  ?  本身是正则元字符，需要反斜杠转义） 

 “先找到一个  / ，然后连续抓取后面既不是  /  也不是  ?  的字符（至少 1 个），直到遇见一个字面问号为止。”
在 MySQL DSN 里就把库名拎出来了

*/


	re := regexp.MustCompile(`/([^/?]+)\?`) 
	matches := re.FindStringSubmatch(url)
	if len(matches) <= 0 {
		panic("创建数据库失败，未找到数据库名称")
	}
	dbName := matches[1] //正则匹配，第 0 个元素是整个串，第 1 个是库名。
	copyUrl := string(url)
	copyUrl = strings.ReplaceAll(copyUrl, dbName, "") //生成“无库名”的临时 DSN，用来先连到 MySQL 的默认库

	db, err := gorm.Open(mysql.Open(copyUrl), &gorm.Config{}) //用临时 DSN 建立第一条连接，权限足就能执行  CREATE DATABASE 。
	if err != nil {
		panic(err)
	}
	//执行数据库穿件 //Exec就是原始的sql语句
	err = db.Exec("CREATE DATABASE IF NOT EXISTS " + dbName + " DEFAULT CHARACTER SET utf8mb4 DEFAULT COLLATE utf8mb4_general_ci;").Error //真正建库，字符集  utf8mb4  + 排序  utf8mb4_general_ci 
	if err != nil {
		panic(err)
	}
	//再次链接
	db, err = gorm.Open(mysql.Open(url), &gorm.Config{})
	return db
}

// 自动建表
func autoCreateTable(db *gorm.DB) {
	db.AutoMigrate(&model.Users{})
	db.AutoMigrate(&model.Post{})
	db.AutoMigrate(&model.Comments{})
}
